/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(30/04/25)
 *         Author:  chenhongyu0822@163.com
 *      ChangeLog:  1, Release initial version on "30/04/25 22:15:46"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <getopt.h>
#include <unistd.h>
#include <sqlite3.h>
#include <time.h>
#include <stdint.h>

#include "client.h"
#include "getdata.h"
#include "tempdb.h"
#include "logger.h"

int main (int argc, char **argv)
{
    char                          *servip=NULL;
    int                           port=0;
	socket_ctx_t                  sock;
    int                           interval=0;
    int                           rv=-1;
    int                           opt;
	Sample_Data_t                 data,temp_data;
	int                           buf_bytes=0;
	pack_data_t                   packet=segmented_pack;
	//pack_data_t                   packet=json_pack;
	//pack_data_t                   packet=tlv_pack;
	char                          buf[1024];
    sqlite3                       *db;
	char                          table_name[28]="TEMP";
	int                           flag;
	time_t                        last_time=0;
	time_t                        now_time;
    struct option                 long_options[]={
    {"addr", required_argument, NULL, 'i'},
    {"port", required_argument, NULL, 'p'},
    {"time", required_argument, NULL, 't'},
    {"help", no_argument, NULL, 'h'},
    {0, 0, 0, 0},
    };

    while((opt =getopt_long(argc, argv, "i:p:t:h", long_options, NULL))!=-1)
    {
        switch(opt)
        {
            case'i':
                servip=optarg;
                break;
            case'p':
                port=atoi(optarg);
                break;
            case't':
                interval=atoi(optarg);
                break;
            case'h':
                print_usage(argv[0]);
                return EXIT_SUCCESS;
            default:
                break;
		}
    }

    if(!servip||!port||!interval)
    {
        print_usage(argv[0]);
        return -1;
    }

	log_open("client.log", LOG_LEVEL_DEBUG, 1024, LOG_LOCK_DISABLE);

    if(tempdb_init(&db, "tempdb.db", table_name)<0)
    {
		log_error("Tempdb initialization faliure:%s\n",strerror(errno));
		sqlite3_close(db);
        return -2;
    }

	client_init(&sock, servip, port);
	client_connect(&sock);

    while(1)
	{
		flag=0;
		now_time=time(NULL);

		if(difftime(now_time, last_time)>=interval)
		{
			last_time=now_time;
 			
			if((rv=get_temperature(&data.temp))<0)
			{
            	log_error("get temperature faliure[%d]:%s\n", rv, strerror(errno));
				continue;
        	}
			
			get_id(data.rpi, sizeof(data.rpi));
			get_time(data.time, sizeof(data.time));
	
			buf_bytes=packet(&data, (uint8_t *)buf, sizeof(buf));	
			if (buf_bytes < 0) 
			{
				log_error("Packet packing failed!\n");
				continue;
			}

			log_info("get data:%s successfully!\n", buf);


			flag=1;
		}

		if(socket_check(&sock)<0)
        {
			printf("Socket connect failure,try to reconnect.\n");
			log_info("Socket connect failure,try to reconnect.\n");
			close(sock.fd);
			client_connect(&sock);
			if(socket_check(&sock)<0)
			{
				if(flag)
				{
            		if(insert_data(db, table_name, data)<0)
            		{
						log_error("Save data to tempdb failure:%s\n", strerror(errno));
            		}
            		else
            		{
						log_info("Save data to tempdb successfully!\n");
            		}
				}
				continue;
        	}

		}

		if(flag)
		{
        	if(client_send(&sock, buf, buf_bytes) < 0 )
        	{
				if(insert_data(db, table_name, data)<0)
				{
					log_error("Save data to tempdb failure:%s\n", strerror(errno));
				}
				else
				{
					log_info("Save data to tempdb successfully!\n");
				}
				continue;
        	}

		}
		
        if(is_tempdb_empty(db, table_name)>0)
		{
			if(fetch_data(db, table_name, &temp_data)<0)
			{
				log_error("Fetch data from tempdb failure: %s\n", strerror(errno));
				continue;
			}
			
			log_info("Fetch data from tempdb successfully!\n");

		 	buf_bytes=packet(&temp_data, buf, sizeof(buf));

			if(client_send(&sock, buf, buf_bytes) < 0 )
			{
				log_error("Send temp data to server faliure:%s\n", strerror(errno));
				continue;
			}
			else
			{
				log_info("The data has been successfully sent from tempdb.\n");

				if(delete_data(db, table_name, temp_data)<0)
				{
					log_error("Delete temp data faliure:%s\n", strerror(errno));
					continue;
				}
				log_info("The data sent has been successfully deleted!\n");
			}
		}

	}

    close(sock.fd);
    sqlite3_close(db);
	log_close();
    return 0;
}




